package com.cal.utms.model.user_maintenance;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.cal.utms.dao.user_maintenance.UserDaoImpl;
import com.cal.utms.dto.user_maintenance.UserDto;
import com.cal.utms.entity.User;

public class UserModel {

	UserDaoImpl daoImpl = new UserDaoImpl();
	private static final char[] PASSWORD = "enfldsgbnlsngdlksdsgm".toCharArray();
	private static final byte[] SALT = { (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, };

	public static User createUserModel(UserDto userDto) {
		UserDaoImpl daoImpl = new UserDaoImpl();
		User user = null;
		try {
			user = new User();
			user.setUserName(userDto.getUserName());
			user.setGender(userDto.getGender());
			user.setEmail(userDto.getEmail());
			user.setDesignation(userDto.getDesignation());
			user.setPassword(encrypt(userDto.getPassword()));
			user.setPhone(userDto.getPhone());
			user.setFullName(userDto.getFullName());
			user.setUserGroup(daoImpl.getUserGroupById(userDto.getUserGroupId()));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}
		return user;
	}

	public static boolean createUserDtoModle(User user) {
		boolean flag = false;
		if (user != null) {
			flag = true;
		}
		return flag;
	}

	public static List<UserDto> createUserDtoList(List<User> users) {
		List<UserDto> userDtos = new ArrayList<UserDto>();
		for (User user : users) {
			UserDto dto = new UserDto();
			dto.setDesignation(user.getDesignation());
			dto.setEmail(user.getEmail());
			dto.setFullName(user.getFullName());
			dto.setGender(user.getGender());
			dto.setId(user.getId());
			try {
				dto.setPassword(decrypt(user.getPassword()));
			} catch (GeneralSecurityException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			dto.setPhone(user.getPhone());
			dto.setUserGroupId(user.getUserGroup().getId());
			dto.setUserName(user.getUserName());
			userDtos.add(dto);
		}
		return userDtos;
	}

	public static String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException {
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
		SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
		Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
		pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
		return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8")));
	}

	private static String base64Encode(byte[] bytes) {
		return new BASE64Encoder().encode(bytes);
	}

	private static String decrypt(String property) throws GeneralSecurityException, IOException {
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
		SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
		Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
		pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
		return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
	}

	private static byte[] base64Decode(String property) throws IOException {
		return new BASE64Decoder().decodeBuffer(property);
	}

	public static User createUserModelWithId(UserDto userDto) {
		UserDaoImpl daoImpl = new UserDaoImpl();
		User user = null;
		try {
			user = new User();
			user.setId(userDto.getId());
			user.setUserName(userDto.getUserName());
			user.setGender(userDto.getGender());
			user.setEmail(userDto.getEmail());
			user.setDesignation(userDto.getDesignation());
			user.setPassword(encrypt(userDto.getPassword()));
			user.setPhone(userDto.getPhone());
			user.setFullName(userDto.getFullName());
			user.setUserGroup(daoImpl.getUserGroupById(userDto.getUserGroupId()));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}
		return user;
	}

	public String saveUser(UserDto userDto) {
		if (daoImpl.getUserByUsername(userDto.getUserName().toUpperCase()) == null) {
			Object object = daoImpl.saveUser(UserModel.createUserModel(userDto));
			if (object instanceof Integer) {
				userDto.setId((Integer) object);
				userDto.setSuccess(true);
				userDto.setResultMsg("Saved Successfully");
			} else {
				userDto.setSuccess(false);
				userDto.setResultMsg("There is some error returned from the server.");
			}
		} else {
			userDto.setSuccess(false);
			userDto.setResultMsg("User name already exists");
		}
		return userDto.getResultMsg();
	}
}
